#ifndef __XKK_EVENTLOOP_H__
#define __XKK_EVENTLOOP_H__

#include "MutexLock.hpp"
#include <sys/epoll.h>

#include <functional>
#include <memory>
#include <vector>
#include <map>

using namespace std;

namespace xkk
{

class Acceptor;
class TcpConnection;

using TcpConnectionPtr=shared_ptr<TcpConnection>;
using TcpConnectionCallback=function<void(const TcpConnectionPtr&)>;
using Functor=function<void()>;

class EventLoop
{
public:
    EventLoop(Acceptor &acceptor); 

    void loop();
    void unloop();
    void runInLoop(Functor &&cb);

    void setConnectionCallback(TcpConnectionCallback &&cb)
    { _onConnection=std::move(cb); }
    void setMessageCallback(TcpConnectionCallback &&cb)
    { _onMessage=std::move(cb); }
    void setCloseCallback(TcpConnectionCallback &&cb)
    { _onClose=std::move(cb); }
private:
    void waitEpollFd();
    void handleNewConnection();
    void handleMessage(int);

    int createEventfd();
    void handleRead();
    void wakeup();
    void doPendingFunctors();

    int createEpollfd();
    void addEpollReadFd(int);
    void delEpollReadFd(int);

    bool isConnectionClosed(int fd);
private:
    int _efd;
    int _eventfd;
    Acceptor &_acceptor;

    vector<struct epoll_event>_evtList;
    map<int ,TcpConnectionPtr>_conns;
    bool _isLooping;

    vector<Functor> _pendingFunctors;
    MutexLock _mutex;

    TcpConnectionCallback _onConnection;
    TcpConnectionCallback _onMessage;
    TcpConnectionCallback _onClose;
};

}//namespace xkk
#endif
